iT邦幫忙

2024 iThome 鐵人賽

DAY 2
0

變數聲明


了解 JavaScript 中 varletconst 的使用非常重要,因為它可以確保正確的變數範圍管理,防止不必要的重新分配,並促進更清晰、更易於維護的程式碼。

變數(variable)是什麼?
變數就像魔法盒,在 JavaScript 中,我們使用變數來儲存東西。
想像一個神奇的盒子,可以容納任何東西,包括一個數字、一個單字,甚至一個不知道值得內容。

宣告變數 - varletconst (letconst 在 ES6 出現)
var:function scope,如果放在 {} 一樣屬於全域變數,且可以在函式的任何地方訪問,變數可被重新賦值。

function varExample() {
  console.log(x); // undefined (因為 x 被提升但未初始化)
  var x = 5;
  console.log(x); // 5

  if (true) {
    var y = 10;
  }
  console.log(y); // 10 (var 的作用域是函式範圍,y 在 if 區塊外仍然可訪問)
}

varExample();

let:block scope,如果放在 {} 就屬於區域變數,但在初始化之前不可訪問(暫時死區 TDZ),算是一個可隨意更改其內容的區塊區域變數,其實 let 範圍容忍性很大。

function letExample() {
  console.log(x); // ReferenceError: Cannot access 'x' before initialization
  let x = 5;
  console.log(x); // 5

  if (true) {
    let y = 10;
    console.log(y); // 10 (y 在 if 區塊內可訪問)
  }
  console.log(y); // ReferenceError: y is not defined (y 在 if 區塊外不可訪問)
}

letExample();

const:block scope,如果放在 {} 就屬於區域變數,但在初始化之前不可訪問(暫時死區 TDZ),一個只可讀取的「不可變」常數,所以最常用在不會改變的變數,重點在「不會改變」

function constExample() {
  console.log(x); // ReferenceError: Cannot access 'x' before initialization
  const x = 5;
  console.log(x); // 5

  if (true) {
    const y = 10;
    console.log(y); // 10 (y 在 if 區塊內可訪問)
  }
  console.log(y); // ReferenceError: y is not defined (y 在 if 區塊外不可訪問)

  x = 20; // TypeError: Assignment to constant variable (const 變數不可重新賦值)
}

constExample();

各種變數的作用域

資料類型(Number, String, Boolean, Object, Array, Null, Undefined)


型別在程式語言中有分成靜態和動態,其中,JavaScript 是動態型別語言,會在執行中不斷轉換,也就是值的本身具備型別,值賦予到變數上時,變數的型別就會來自於值。

靜態型別:編譯時就知道變數型別
動態型別:執行時才知道變數型別

在文件中共有 7+1 種型別,主要分成兩大類:原始型別和物件型別,可以使用 typeof 看型別種類。

// 原始型別,不能擴增屬性!
console.log(typeof 'luanIsPig');     // string
console.log(typeof 1);               // number
console.log(typeof true);            // boolean
console.log(typeof 100n);            // bigint → 就是輸入一個數字後面再加上一個 n 
console.log(typeof Symbol(1));       // symbol → 原始型別,就是一個 Symbol 後面接一個數字
console.log(typeof undefined);       // undefined
console.log(typeof null);            // object → 這裡比較特別,是一個早期的錯誤實際上是獨立型別null

🔔 0, null, undefined 差別
0, null, undefined 差別
圖片來源:Difference between non-zero value, 0, null & undefined in Javascript

// 物件型別可以自由擴增屬性!
console.log(typeof {});              // object
console.log(typeof []);              // object
console.log(typeof function() {});   // function → 但是實際上沒有 function 型別所以歸類在 object
console.log(typeof /12345/);         // object → 正規表達式也是物件
// 原始型別包裹物件就是當我們宣告原是型別時,所包裹進來的方法
let myName = '   Kuku   ';
console.log(typeof myName);         // string
console.log(myName.length);         // 10
console.log(myName.trim());         // Kuku
console.log(myName.trim().length);  // 4

類型轉換


JavaScript 是弱型別,很常出現型別轉來轉去的困擾;型別分為兩大類型:顯性轉換和隱性轉換,但實際上這 2 種在轉換過程沒有明確的區分,所以只能用主流大概分類說明:

顯性轉換
一眼看出是什麼型別轉換,相對單純,職場經驗中很常用到

// 數值轉換
console.log(Number('123'));            // 123
console.log(Number('abc'));            // NaN
console.log(parseInt('123px'));        // 123
console.log(parseFloat('12.34abc'));   // 12.34

// 字串轉換
console.log(String(123));              // '123'
console.log(String(true));             // 'true'

// 布林值轉換
console.log(Boolean(0));               // false
console.log(Boolean('text'));          // true

隱性轉換

// 一元正負運算子「一定」會轉成數字型別,所以關鍵!一定要先判斷是否為一元運算子!
console.log(+'1');                    // 1
console.log(typeof (+'1'));           // number
console.log(+'50元');                 // NaN
console.log(typeof (+'50元'));        // number

// 前後運算元如果其中之一為 “字串” 型別,+ 視為字串運算子
console.log('5' + 2);                 // '52'(字串拼接)

// 前後運算元如果無法轉型為原始型別(就是指物件型別),+ 視為字串運算子
console.log(1 + {});                  // 1[object Object]
console.log(1 + []);                  // 1[]

// 布林值可以轉成數字,而且不是字串也不是物件,+ 視為算術運算子
console.log(1 + true);                // 2

型別比較


寬鬆相等 (==,筆試比較會考到):進行隱性類型轉換,若類型不同則自動轉換後比較。
嚴格相等 (===,開發比較會用到):嚴格比較,要求類型和值都必須相等。

console.log(1 === '1');              // false
console.log(1 == '1');               // true

// 開發曾經踩過的坑:嚴格比較例外狀況
console.log(undefined === null);               // false,型別不一樣
console.log({} === {});                        // false,原理在吃的記憶體位置不一樣
console.log([] === []);                        // false,原理在吃的記憶體位置不一樣 ⭐
console.log(new Number(0) === new Number(0));  // false,原始型別包裹物件產生新的值也是物件型別

真假值表


真假值對照表


上一篇
第 1 天:JavaScript 概述與環境配置
下一篇
第 3 天:操作符和控制流
系列文
30天 JavaScript 提升計畫:從零到精通結合2024年的創新功能30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言